package com.asen.commons.core.utils;

//import com.asen.commons.base.controller.AbstractListController;
import com.asen.commons.core.base.vo.DcPage;
        import com.asen.commons.core.meta.entity.EntityField;
        import com.asen.commons.core.meta.helper.EntityFieldHelper;
        import com.asen.commons.utils.*;
        import com.asen.commons.core.base.result.ApiResult;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;

        import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Field工具类
 *
 * @author ls
 * @version 1.0
 * @date 2024-04-10
 */
@Slf4j
public class FieldUtils {

    private final static Map<String, String> stripClassMap = new HashMap<>();

    private final static String RESULT = "result";

    private final static String LIST = "list";

    static {
        stripClassMap.put(ApiResult.class.getName(), RESULT);
        stripClassMap.put(DcPage.class.getName(), LIST);
        stripClassMap.put(PageInfo.class.getName(), LIST);
    }

    protected static Map<Class<?>, List<EntityField>> fieldListMap = new ConcurrentHashMap<>();

    public static List<EntityField> getFieldList(Class<?> clazz) {
        BaseAssert.notNull(clazz, "参数clazz不能为空");
        List<EntityField> fieldList = fieldListMap.get(clazz);
        if (fieldList == null) {
            synchronized (clazz) {
                fieldList = EntityFieldHelper.getAllFields(clazz);
                fieldListMap.put(clazz, fieldList);
            }
        }
        return fieldList;
    }

    //public static EntityField getField(List<EntityField> fieldList, String name) {
    //    if (fieldList == null || name == null) {
    //        return null;
    //    }
    //
    //    EntityField result = null;
    //    for (EntityField ef : fieldList) {
    //        if (ef.getName().equals(name)) {
    //            result = ef;
    //            break;
    //        }
    //    }
    //
    //    return result;
    //}

    //public static Object getFieldValue(Class<?> clazz, String fieldName, Object model) throws Exception {
    //    return getFieldValue(getFieldList(clazz), fieldName, model);
    //}

    //public static Object getFieldValue(List<EntityField> fieldList, String name, Object model) throws Exception {
    //    Object result = null;
    //
    //    EntityField ef = getField(fieldList, name);
    //    if (ef != null) {
    //        result = ef.getValue(model);
    //    }
    //
    //    return result;
    //}

    /**
     * 字段对象转成转成FieldVo
     */
    //public static List<FieldVo> toFieldVo(List<FieldObject> fieldList, Map<String, String> typeMap) throws Exception {
    //    if (CollectionUtils.isEmpty(fieldList)) {
    //        return null;
    //    }
    //    List<FieldVo> result = new ArrayList<>();
    //    fieldList.forEach(item -> buildField(item, result, typeMap));
    //    return result;
    //}

    //private static void buildField(FieldObject item, List<FieldVo> result, Map<String, String> typeMap) {
    //    if ("serialVersionUID".equals(item.getName())) {
    //        return;
    //    }
    //    FieldVo fieldVo = new FieldVo();
    //    fieldVo.setName(item.getName());
    //    fieldVo.setAlias(item.getAlias());
    //    fieldVo.setJavaType(item.getJavaType().getName());
    //    fieldVo.setColumn(item.getColumn());
    //    try {
    //        fieldVo.setColumnType(item.getColumnType());
    //    } catch (Exception e) {
    //    }
    //    fieldVo.setType("Normal");
    //    if (item.isDict()) {
    //        fieldVo.setType("Dict");
    //    }
    //    if (item.isEnum()) {
    //        fieldVo.setType("Enum");
    //    }
    //    if (item.isReference()) {
    //        fieldVo.setType("Reference");
    //    }
    //    if (item.isSub()) {
    //        fieldVo.setBillType(item.getJavaType().getName());
    //    } else if (item.isEntry()) {
    //        Type[] args = item.getActualParameterTypeArgs();
    //        if (args != null && args.length == 1) {
    //            Type type = args[0];
    //            if (type instanceof Class) {
    //                Class<?> aClass = (Class<?>) type;
    //                if (Core.class.isAssignableFrom(aClass)) {
    //                    fieldVo.setBillType(aClass.getName());
    //                }
    //            }
    //        }
    //    }
    //    if (item.isEnum()) {
    //        fieldVo.setEnumList(EnumUtils.enumItemList(item.getEnumType()));
    //    }
    //    if (item.isDateFormat()) {
    //        fieldVo.setDateFormat(item.getDateFormat());
    //    }
    //    // 构建泛型字段
    //    buildGenericityField(fieldVo, item, typeMap);
    //
    //    // 构架查询类型
    //    FieldQueryTypeEnum.setQueryType(fieldVo);
    //
    //    result.add(fieldVo);
    //
    //    // 扩展属性
    //    buildExtFields(result, item.getField(), item.getAlias());
    //}

    //private static void buildExtFields(List<FieldVo> result, Field field, String fieldAlias) {
    //    if (field.isAnnotationPresent(FieldBillType.class)) {
    //        FieldBillType fieldBillType = field.getAnnotation(FieldBillType.class);
    //        if (fieldBillType.typeOnly()) {
    //            return;
    //        }
    //
    //        FieldVo fieldVo = new FieldVo();
    //        fieldVo.setName(field.getName() + "Name");
    //        fieldVo.setAlias(fieldAlias + "名称");
    //        fieldVo.setJavaType(String.class.getName());
    //        fieldVo.setType("Extend");
    //        result.add(fieldVo);
    //    }
    //
    //    if (field.isAnnotationPresent(FieldDict.class)) {
    //        FieldDict fieldDict = field.getAnnotation(FieldDict.class);
    //        if (fieldDict.typeOnly()) {
    //            return;
    //        }
    //
    //        FieldVo fieldVo = new FieldVo();
    //        fieldVo.setName(field.getName() + "Label");
    //        fieldVo.setAlias(fieldAlias + "标签");
    //        fieldVo.setJavaType(String.class.getName());
    //        fieldVo.setType("Extend");
    //        result.add(fieldVo);
    //    }
    //
    //    if (field.isAnnotationPresent(FieldEnum.class)) {
    //        FieldEnum fieldEnum = field.getAnnotation(FieldEnum.class);
    //        if (fieldEnum.typeOnly()) {
    //            return;
    //        }
    //
    //        FieldVo fieldVo = new FieldVo();
    //        fieldVo.setName(field.getName() + "Desc");
    //        fieldVo.setAlias(fieldAlias + "描述");
    //        fieldVo.setJavaType(String.class.getName());
    //        fieldVo.setType("Extend");
    //        result.add(fieldVo);
    //    }
    //
    //    if (field.isAnnotationPresent(FieldReference.class)) {
    //        FieldReference fieldReference = field.getAnnotation(FieldReference.class);
    //        if (fieldReference.typeOnly()) {
    //            return;
    //        }
    //
    //        String refName = field.getName();
    //        if (refName.endsWith("Id")) {
    //            refName = StringUtils.removeLastWord(refName);
    //        }
    //
    //        if (fieldAlias.endsWith("id")) {
    //            fieldAlias = fieldAlias.substring(0, fieldAlias.length() - 2);
    //        }
    //
    //        String attrs = fieldReference.attrs();
    //        if (StringUtils.isNotEmpty(attrs)) {
    //            for (String attr : attrs.split(",")) {
    //                String propName = attr.trim();
    //                String displayName = null;
    //                int index = attr.indexOf(":");
    //                if (index > 0) {
    //                    propName = attr.substring(0, index);
    //                    displayName = attr.substring(index + 1);
    //                } else {
    //                    propName = attr;
    //                    displayName = refName + StringUtils.firstAlpha2UpperCase(propName);
    //                }
    //
    //                FieldVo fieldVo = new FieldVo();
    //                fieldVo.setName(displayName);
    //                fieldVo.setAlias(fieldAlias + propName);
    //                fieldVo.setJavaType(String.class.getName());
    //                fieldVo.setType("Extend");
    //                result.add(fieldVo);
    //            }
    //        } else {
    //            String displayName = refName + "Name";
    //
    //            FieldVo fieldVo = new FieldVo();
    //            fieldVo.setName(displayName);
    //            fieldVo.setAlias(fieldAlias + "名称");
    //            fieldVo.setJavaType(String.class.getName());
    //            fieldVo.setType("Extend");
    //            result.add(fieldVo);
    //        }
    //    }
//        if (field.isAnnotationPresent(FieldRefUnit.class)) {
//            FieldRefUnit refUnit = field.getAnnotation(FieldRefUnit.class);
//            if (refUnit.typeOnly()) {
//                return;
//            }
//            String refName = field.getName();
//            if (refName.endsWith("Id")) {
//                refName = StringUtils.removeLastWord(refName);
//            }
//            if (refUnit.showName()) {
//                FieldVo fieldVo = new FieldVo();
//                fieldVo.setName(refName + "Name");
//                fieldVo.setAlias(fieldAlias + "名称");
//                fieldVo.setJavaType(String.class.getName());
//                fieldVo.setType("Extend");
//                result.add(fieldVo);
//            }
//            if (refUnit.showNumber()) {
//                FieldVo fieldVo = new FieldVo();
//                fieldVo.setName(refName + "Number");
//                fieldVo.setAlias(fieldAlias + "编码");
//                fieldVo.setJavaType(String.class.getName());
//                fieldVo.setType("Extend");
//                result.add(fieldVo);
//            }
//        }
//    }

    /**
     * 构建泛型字段
     */
    //private static void buildGenericityField(FieldVo fieldVo, FieldObject item, Map<String, String> typeMap) {
    //    Field field = item.getField();
    //    Type genericType = field.getGenericType();
    //    if (genericType == null) {
    //        return;
    //    }
    //    String className = field.getDeclaringClass().getName();
    //    String name;
    //    if (genericType instanceof ParameterizedTypeImpl) {
    //        ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) genericType;
    //        Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0];
    //        if (actualTypeArgument instanceof Class) {
    //            buildFieldByClass(((Class) actualTypeArgument).getName(), fieldVo, typeMap);
    //            return;
    //        }
    //        name = actualTypeArgument.getTypeName();
    //    } else {
    //        name = genericType.getTypeName();
    //    }
    //    String key = getTypeKey(className, name);
    //    String typeClassName = SUtil.get(typeMap, key);
    //    if (StringUtils.isBlank(typeClassName)) {
    //        return;
    //    }
    //    if (List.class.getName().equals(typeClassName)) {
    //        key = getTypeKey(typeClassName, "E");
    //        typeClassName = SUtil.get(typeMap, key);
    //        if (StringUtils.isBlank(typeClassName)) {
    //            return;
    //        }
    //    }
    //    buildFieldByClass(typeClassName, fieldVo, typeMap);
    //}

    //public static void buildFieldByClass(String className, FieldVo fieldVo, Map<String, String> typeMap) {
    //    try {
    //        Class<?> clazz = Class.forName(className);
    //        if (EntityUtils.isSimpleType(clazz)) {
    //            return;
    //        }
    //        EntityObject eo = EntityObjectLoader.getInstance().load(clazz);
    //        List<FieldObject> fieldList = eo.getFieldList();
    //        List<FieldVo> voList = toFieldVo(fieldList, typeMap);
    //
    //        fieldVo.setJavaType(className);
    //        fieldVo.setBillType(className);
    //        fieldVo.setFieldList(voList);
    //    } catch (Exception e) {
    //        log.error("反射类名失败,typeClassName:{},原因:{}", className, e);
    //    }
    //}

    //public static void buildFieldTypeMap(Type genericParameterType, Map<String, String> typeMap) throws Exception {
    //    if (!(genericParameterType instanceof ParameterizedTypeImpl)) {
    //        return;
    //    }
    //    ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) genericParameterType;
    //    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
    //    if (actualTypeArguments.length == 0) {
    //        return;
    //    }
    //    Class<?> rawType = parameterizedType.getRawType();
    //    TypeVariable<? extends Class<?>>[] typeParameters = rawType.getTypeParameters();
    //
    //    String className = rawType.getName();
    //    for (int i = 0; i < actualTypeArguments.length; i++) {
    //        Type actualTypeArgument = actualTypeArguments[i];
    //        TypeVariable<? extends Class<?>> parameter = typeParameters[i];
    //
    //        String typeName;
    //        if (actualTypeArgument instanceof ParameterizedTypeImpl) {
    //            ParameterizedTypeImpl typeImpl = (ParameterizedTypeImpl) actualTypeArgument;
    //            typeName = typeImpl.getRawType().getName();
    //        } else if (actualTypeArgument instanceof Class) {
    //            Class<?> clazz = (Class<?>) actualTypeArgument;
    //            typeName = clazz.getName();
    //        } else {
    //            continue;
    //        }
    //        String name = parameter.getName();
    //
    //        String key = getTypeKey(className, name);
    //        typeMap.put(key, typeName);
    //        Type superclass = rawType.getGenericSuperclass();
    //        if (superclass != null && superclass != Object.class) {
    //            if (superclass instanceof ParameterizedTypeImpl) {
    //                key = getTypeKey(((ParameterizedTypeImpl) superclass).getRawType().getTypeName(), name);
    //                typeMap.put(key, typeName);
    //            } else {
    //                key = getTypeKey(superclass.getTypeName(), name);
    //                typeMap.put(key, typeName);
    //            }
    //        }
    //
    //        // 递归构建
    //        buildFieldTypeMap(actualTypeArgument, typeMap);
    //    }
    //}

    private static String getTypeKey(String className, String name) {
        return className + "#" + name;
    }

    /**
     * 拆除 ApiResult DcPage PageInfo 外层
     */
    //public static List<FieldVo> stripType(String name, List<FieldVo> fieldVoList) {
    //    if (!stripClassMap.containsKey(name) || CollectionUtils.isEmpty(fieldVoList)) {
    //        return fieldVoList;
    //    }
    //    String field = stripClassMap.get(name);
    //    if (StringUtils.isBlank(field)) {
    //        return fieldVoList;
    //    }
    //    FieldVo fieldVo = fieldVoList.stream().filter(item -> field.equals(item.getName())).findFirst().orElse(null);
    //    if (fieldVo == null) {
    //        return fieldVoList;
    //    }
    //    return stripType(fieldVo.getJavaType(), fieldVo.getFieldList());
    //}

    /**
     * 标准框架的接口内置map
     */
    //public static void buildCoreMap(MethodParameter methodParameter, Map<String, String> typeMap) {
    //    if (methodParameter.getMethod() == null) {
    //        return;
    //    }
    //    Class<?> pClass = methodParameter.getContainingClass();
    //    // TODO
    //    if (AbstractListController.class.isAssignableFrom(pClass) && LIST.equals(methodParameter.getMethod().getName())) {
    //        ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) pClass.getGenericSuperclass();
    //        Type actParams = parameterizedType.getActualTypeArguments()[0];
    //        String typeName = "";
    //        if (actParams instanceof ParameterizedTypeImpl) {
    //            ParameterizedTypeImpl typeImpl = (ParameterizedTypeImpl) actParams;
    //            typeName = typeImpl.getRawType().getName();
    //        } else if (actParams instanceof Class) {
    //            Class<?> clazz = (Class<?>) actParams;
    //            typeName = clazz.getName();
    //        }
    //        typeMap.put(getTypeKey(DcPage.class.getName(), "T"), typeName);
    //    }
    //    if (AbstractListController.class.isAssignableFrom(pClass) && "get".equals(methodParameter.getMethod().getName())) {
    //        ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) pClass.getGenericSuperclass();
    //        Type actParams = parameterizedType.getActualTypeArguments()[2];
    //        String typeName = "";
    //        if (actParams instanceof ParameterizedTypeImpl) {
    //            ParameterizedTypeImpl typeImpl = (ParameterizedTypeImpl) actParams;
    //            typeName = typeImpl.getRawType().getName();
    //        } else if (actParams instanceof Class) {
    //            Class<?> clazz = (Class<?>) actParams;
    //            typeName = clazz.getName();
    //        }
    //        typeMap.put(getTypeKey(ApiResult.class.getName(), "T"), typeName);
    //    }
    //}
}
